#include "TcpServer.hpp"
#include "Protocol.hpp"
#include "Calculator.hpp"
#include <memory>

using cal_f = std::function<Response(const Request &req)>;

// 解析模块
class Parse
{
public:
    Parse(cal_f cal) : _cal(cal) 
    {};

    // package不一定完整
    std::string Entry(std::string &package)
    {
        // 1.判断报文的完整性
        std::string message;
        std::string respstr;
        while (Decode(package, &message))
        {
            LOG(LogLevel::DEBUG) << "content: \n" << message;
            if (message.empty())
                break;

            // 2.反序列化
            Request req;
            if (!req.Deserialize(message))
                break;
            std::cout << "----------------" << std::endl;
            req.Print();
            std::cout << "----------------" << std::endl;

            // 3.计算
            Response resp = _cal(req);

            // 4.序列化
            std::string res;
            resp.Serialize(res);
            LOG(LogLevel::DEBUG) << "序列化: \n" << res;

            // 5.添加长度报头字段
            Encode(res);
            LOG(LogLevel::DEBUG) << "Encode: \n" << res;

            // 6.拼接应答
            respstr += res;
        }
        LOG(LogLevel::DEBUG) << "respstr: \n" << respstr;
        return respstr;
    }

private:
    cal_f _cal;
};

int main()
{
    ENABLE_CONSOLE_LOG();
    // Command cmd;

    // std::unique_ptr<TcpServer> ts = std::make_unique<TcpServer>([&cmd](const std::string& cmd_str){
    //     return cmd.Execute(cmd_str);
    // });
    // ts->InitTcpServer();
    // ts->Start();

    // 1.计算模块
    Calculator cal;
    // 2.解析模块
    Parse myparse([&cal](const Request& req){
        return cal.Execute(req);
    });
    // 3.通信模块
    // 只负责IO
    std::unique_ptr<TcpServer> ts = std::make_unique<TcpServer>([&myparse](std::string &package){
        return myparse.Entry(package);
    });

    ts->InitTcpServer();
    ts->Start();

    return 0;
}